package com.yx.changdao.web.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yx.changdao.common.annotation.AutoLog;
import com.yx.changdao.common.annotation.ShiroDesc;
import com.yx.changdao.common.data.Result;
import com.yx.changdao.common.entity.*;
import com.yx.changdao.common.exception.AlertException;
import com.yx.changdao.common.utils.*;
import com.yx.changdao.common.vo.BuildBuildVo;
import com.yx.changdao.common.vo.ResidentSelectVo;
import com.yx.changdao.service.*;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.nutz.ioc.aop.Aop;
import org.nutz.json.Json;
import org.nutz.lang.Strings;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ResourceUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import javax.validation.constraints.NotNull;
import java.io.File;
import java.io.IOException;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


/**
 * @Description: <br/>
 * 居民信息表
 * <p>
 * <br/>
 * @Auther: flexible
 * @create 2020/04/02 14:20
 */
@Validated
@RestController
@RequestMapping("community/resident")
public class CommunityResidentController {
    /**
     * 字典表服务
     */
    @Autowired
    private SysDictService sysDictService;
    @Autowired
    private GridInfoService gridInfoService;

    @Autowired
    private CommunityVillageService communityVillageService;
    @Autowired
    private CommunityTownshipService communityTownshipService;
    // 社区建筑物表服务
    @Autowired
    private CommunityBuildService communityBuildService;
    // 户信息表服务
    @Autowired
    private CommunityBuildDetailService communityBuildDetailService;
    /**
     * 居民信息表服务
     */
    @Autowired
    private CommunityResidentService communityResidentService;
    @Autowired
    private SysUserService sysUserService;
    /**
     * 建筑物联户组关联服务
     */
    @Autowired
    private ContactGroupBuildService contactGroupBuildService;

    /**
     * 列表
     * stats：状态（0:已安置 1：未安置）
     *
     * @return Result
     */
    @AutoLog
    @GetMapping("/list")
    /*@RequiresPermissions("community:resident:list")
    @ShiroDesc("居民信息表:列表")*/
    public Result list(@RequestParam(value = "page") Long page,
                       @RequestParam(value = "limit", required = false) Integer limit,
                       @RequestParam(value = "stats") Integer stats) throws AlertException, ParseException {
        if (stats == null) {
            return Result.error("stats不允许为空");
        }
        if (limit == null) {
            limit = SysConst.LIMIT_PAGE;
        }
        if (page == null) {
            page = 1L;
        }
        Page<CommunityResident> pager = new Page<>(page, limit);
        /**
         * 根据条件查询出集合
         */
        QueryWrapper<CommunityResident> queryWrapper = SysUtils.autoCnd(CommunityResident.class);
        Page<CommunityResident> communityResidentPage = null;
        if (stats == 0) {
            communityResidentPage = this.communityResidentService.page(pager, queryWrapper.lambda().eq(CommunityResident::getBuildDetailId, 0));
        } else {
            communityResidentPage = this.communityResidentService.page(pager, queryWrapper.lambda().ne(CommunityResident::getBuildDetailId, 0));
        }
        List<CommunityResident> records = communityResidentPage.getRecords();

        dataFormat(records);

        Map<String, Object> map = new HashMap();
        map.put("pager", communityResidentPage);
        map.put("list", records);
        return Result.ok().data(map);
    }


    /**
     * 添加居民信息表
     * regionName:小区名
     * build_name：建筑名（楼号）
     * unit：单元
     * house_number：门牌号
     *
     * @param
     * @return Result
     */
    @AutoLog
    @PostMapping
    public Result add(@Valid @RequestBody CommunityResident communityResident) throws AlertException {
        if (Strings.isNotBlank(communityResident.getLocation())) {
            String[] split = communityResident.getLocation().split(",");
            for (int i = 0; i < split.length; i++) {
                SysDict one = sysDictService.getOne(new QueryWrapper<SysDict>().eq(SysDict.DATA_KEY, split[i]));
                if(i==0){
                    communityResident.setProvince(one.getDataValue());
                }
                if(i==1){
                    communityResident.setCity(one.getDataValue());
                }
                if(i==2){
                    communityResident.setDistrict(one.getDataValue());
                }

            }
        }
        if (Strings.isNotBlank(communityResident.getIdCard())) {
            List<CommunityResident> communityResidents = communityResidentService.
                    list(new QueryWrapper<CommunityResident>().eq(CommunityResident.ID_CARD, communityResident.getIdCard()));
            if (communityResidents.size() != 0) {
                throw new AlertException("该居民已添加");
            }
        }
        if (Strings.isNotBlank(communityResident.getPhone())) {
            boolean matches = communityResident.getPhone().matches("^1[0-9]{10}$");
            if (matches == false) {
                throw new AlertException("请输入正确的居民电话");
            }
        }

        if (communityResident.getBuildDetailId() == null) {
            communityResident.setBuildDetailId(0);
        } else {
            if (Strings.isNotBlank(communityResident.getIdCard())) {
                if (communityResident.getIdCard().length() != 15 && communityResident.getIdCard().length() != 18) {
                    throw new AlertException("身份证不合法");
                }
            }
            //查户
            CommunityBuildDetail communityBuildDetail = communityBuildDetailService.getOne(new QueryWrapper<CommunityBuildDetail>()
                    .eq(CommunityBuildDetail.ID, communityResident.getBuildDetailId()));
            if (communityBuildDetail == null) {
                return Result.error("该户没有绑定楼栋");
            }
            communityResident.setUnit(communityBuildDetail.getUnit());
            CommunityBuild communityBuild = communityBuildService.getOne(new QueryWrapper<CommunityBuild>()
                    .eq(CommunityBuild.ID, communityBuildDetail.getBuildId()));
            if (communityBuild == null) {
                return Result.error("该户没有绑定建筑");
            }
            communityResident.setBuildId(communityBuild.getId());

            GridInfo gridInfo = gridInfoService.getOne(new QueryWrapper<GridInfo>()
                    .eq(GridInfo.ID, communityBuild.getGridId()));
            if (gridInfo == null) {
                return Result.error("该户没有绑定网格");
            }
            communityResident.setGridId(gridInfo.getId());
            //查出村/社区
            CommunityVillage communityVillage = communityVillageService.getOne(new QueryWrapper<CommunityVillage>()
                    .eq(CommunityVillage.ID, gridInfo.getVillageId()));
            if (null == communityVillage) {
                return Result.error("该户没有绑定村/社区");
            }
            communityResident.setVillageId(communityVillage.getId());
            //查出乡镇
            CommunityTownship communityTownship = communityTownshipService.getOne(new QueryWrapper<CommunityTownship>().eq(CommunityTownship.ID, communityVillage.getTownShipId()));
            if (null == communityTownship) {
                return Result.error("该户没有绑定乡镇");
            }
            communityResident.setTownShipId(communityTownship.getId());
        }
        List<CommunityResident> list = communityResidentService.list(new QueryWrapper<CommunityResident>().eq(CommunityResident.BUILD_DETAIL_ID, communityResident.getBuildDetailId())
                .eq(CommunityResident.USER_NAME, communityResident.getUserName()));
        if (list.size() != 0) {
            return Result.error("该居民在该户存在重名情况，请确认");
        }
        boolean b = communityResidentService.save(communityResident);
        if (!b) {
            throw new AlertException("居民信息添加失败");
        }
        List<CommunityResident> one = communityResidentService.
                list(new QueryWrapper<CommunityResident>().eq(CommunityResident.ID_CARD, communityResident.getIdCard()));
        BuildBuildVo buildBuildVo = new BuildBuildVo();
        buildBuildVo.setId(one.get(0).getId());
        buildBuildVo.setName(one.get(0).getUserName());
        return Result.ok("居民信息添加成功").data(buildBuildVo);
    }


    /**
     * 获得指定id 居民信息表。
     *
     * @param
     * @return Result
     */
    @AutoLog
    @GetMapping("/{id}")
    public Result get(@PathVariable("id") String id) throws AlertException {
        CommunityResident communityResident = communityResidentService.getById(id);
        communityResident.setIdCard(DesensitizationUtils.idEncrypt(communityResident.getIdCard()));
        if (communityResident == null) {
            throw new AlertException("未找到相关居民信息");
        }

        if (Strings.isNotBlank(communityResident.getLocation())) {
            String[] split = communityResident.getLocation().split(",");
            List<String> list = new ArrayList<>();
            for (String s : split) {
                list.add(s);
            }
            communityResident.setLocations(list);
        }
        return Result.ok().data(communityResident);
    }


    /**
     * 更新居民信息表
     *
     * @param
     * @return Result
     */
    @AutoLog
    @PutMapping
    public Result update(@Valid @RequestBody CommunityResident communityResident) throws AlertException {
        if (Strings.isNotBlank(communityResident.getLocation())) {
            String[] split = communityResident.getLocation().split(",");
            for (int i = 0; i < split.length; i++) {
                SysDict one = sysDictService.getOne(new QueryWrapper<SysDict>().eq(SysDict.DATA_KEY, split[i]));
                if(i==0){
                    communityResident.setProvince(one.getDataValue());
                }
                if(i==1){
                    communityResident.setCity(one.getDataValue());
                }
                if(i==2){
                    communityResident.setDistrict(one.getDataValue());
                }

            }
        }

        if (Strings.isNotBlank(communityResident.getIdCard())) {
            if (communityResident.getIdCard().length() != 15 && communityResident.getIdCard().length() != 18) {
                throw new AlertException("身份证不合法");
            }
        }
        if (Strings.isNotBlank(communityResident.getPhone())) {
            boolean matches = communityResident.getPhone().matches("^1[0-9]{10}$");
            if (matches == false) {
                throw new AlertException("请输入正确的居民电话");
            }
        }
        if (Strings.isNotBlank(communityResident.getIdCard())) {
            List<CommunityResident> communityResidents = communityResidentService.
                    list(new QueryWrapper<CommunityResident>().eq(CommunityResident.ID_CARD, communityResident.getIdCard()));
            if (communityResidents.size() != 0 && !communityResidents.get(0).getId().equals(communityResident.getId())) {
                throw new AlertException("该居民已添加");
            }
        }

        List<CommunityResident> list = communityResidentService.list(new QueryWrapper<CommunityResident>().eq(CommunityResident.BUILD_DETAIL_ID, communityResident.getBuildDetailId())
                .eq(CommunityResident.USER_NAME, communityResident.getUserName()));
        if (list.size() != 0 && !list.get(0).getId().equals(communityResident.getId())) {
            return Result.error("该居民在该户存在重名情况，请确认");
        }

        //查户
        CommunityBuildDetail communityBuildDetail = communityBuildDetailService.getOne(new QueryWrapper<CommunityBuildDetail>()
                .eq(CommunityBuildDetail.ID, communityResident.getBuildDetailId()));
        if (communityBuildDetail == null) {
            return Result.error("该户没有绑定楼栋");
        }
        communityResident.setUnit(communityBuildDetail.getUnit());
        CommunityBuild communityBuild = communityBuildService.getOne(new QueryWrapper<CommunityBuild>()
                .eq(CommunityBuild.ID, communityBuildDetail.getBuildId()));
        if (communityBuild == null) {
            return Result.error("该户没有绑定建筑");
        }
        communityResident.setBuildId(communityBuild.getId());

        GridInfo gridInfo = gridInfoService.getOne(new QueryWrapper<GridInfo>()
                .eq(GridInfo.ID, communityBuild.getGridId()));
        if (gridInfo == null) {
            return Result.error("该户没有绑定网格");
        }
        communityResident.setGridId(gridInfo.getId());
        //查出村/社区
        CommunityVillage communityVillage = communityVillageService.getOne(new QueryWrapper<CommunityVillage>()
                .eq(CommunityVillage.ID, gridInfo.getVillageId()));
        if (null == communityVillage) {
            return Result.error("该户没有绑定村/社区");
        }
        communityResident.setVillageId(communityVillage.getId());
        //查出乡镇
        CommunityTownship communityTownship = communityTownshipService.getOne(new QueryWrapper<CommunityTownship>().eq(CommunityTownship.ID, communityVillage.getTownShipId()));
        if (null == communityTownship) {
            return Result.error("该户没有绑定乡镇");
        }
        communityResident.setTownShipId(communityTownship.getId());

        boolean b = communityResidentService.updateById(communityResident);
        if (!b) {
            throw new AlertException("居民信息更新失败");
        }

        if (communityResident.getBuildDetailId() != 0) {
            Boolean placement = communityResidentService.placement(communityResident, communityResident.getBuildDetailId());
            if (!placement) {
                throw new AlertException("修改网格，建筑信息时出错");
            }
        }
        return Result.ok("居民信息更新成功");
    }


    /**
     * 删除居民信息表
     *
     * @param
     * @return Result
     */
    @AutoLog
    @DeleteMapping("/{id}")
    public Result delete(@PathVariable("id") String id) throws AlertException {
        String[] split = id.split(",");
        for (String s : split) {
            boolean b = communityResidentService.removeById(s);
            if (!b) {
                throw new AlertException("居民信息删除失败");
            }
        }
        return Result.ok("删除居民信息成功");
    }


    /**
     *
     *  根据id查询户人员列表
     *
     * @param page
     * @param limit
     * @param id 请求id
     * @param type 请求的那一层
     * @param  status 是否是三级 true 三级
     * @return
     * @throws AlertException
     */
    @AutoLog
    @GetMapping("/getByBuildDetailId")
    public Result getAllResidentByBuildDetailId(@RequestParam(value = "page") Long page,
                                                @RequestParam(value = "limit", required = false) Integer limit,
                                                @RequestParam(value = "id", required = false) Integer id,
                                                @RequestParam(value = "type", required = false) Integer type,
                                                @RequestParam(value = "status", required = false) boolean status) throws AlertException, ParseException {
        if (limit == null) {
            limit = SysConst.LIMIT_PAGE;
        }
        if (page == null) {
            page = 1L;
        }

        QueryWrapper<CommunityResident> queryWrapper = SysUtils.autoCnd(CommunityResident.class);
        //只返回已安置的用户
        queryWrapper.ne(CommunityResident.BUILD_DETAIL_ID, 0);
        Page<CommunityResident> pager = new Page<>(page, limit);

        Page<CommunityResident> communityResidentPage = null;
        List<CommunityResident> records = new ArrayList<>();
        if (type == null) {
            if(status==true){

                String userId = SysUtils.currentUserId();
                SysUser sysUser = sysUserService.getOne(new QueryWrapper<SysUser>().eq(SysUser.USER_ID, userId));
                if (sysUser == null) {
                    return Result.error("该帐号不存在");
                }

                List<ContactGroupBuild> contactGroupBuilds = contactGroupBuildService.list(new QueryWrapper<ContactGroupBuild>()
                        .eq(ContactGroupBuild.CONTACT_GROUP_ID, sysUser.getContactGroupId()));
                if (contactGroupBuilds.size() == 0) {
                    return Result.ok().data(records);
                }
                Integer[] gridId = new Integer[contactGroupBuilds.size()];

                for (int i = 0; i < contactGroupBuilds.size(); i++) {
                    CommunityBuild communityBuild = communityBuildService.getOne(new QueryWrapper<CommunityBuild>()
                            .eq(CommunityBuild.ID, contactGroupBuilds.get(i).getBuildId()));
                    if(communityBuild==null){
                        continue;
                    }
                    GridInfo gridInfo = gridInfoService.getOne(new QueryWrapper<GridInfo>().eq(GridInfo.ID, communityBuild.getGridId()));
                    if(gridInfo==null){
                        continue;
                    }
                    gridId[i]=communityBuild.getGridId();
                }
                List<CommunityBuild> communityBuilds = communityBuildService.list(new QueryWrapper<CommunityBuild>().in(CommunityBuild.GRID_ID, gridId));
                if (communityBuilds.size() == 0) {
                    return Result.ok().data(records);
                }
                List<Integer> buildList=new ArrayList<>();
                Integer[] buildId= new Integer[communityBuilds.size()];
                for (int i = 0; i < communityBuilds.size(); i++) {
                    ContactGroupBuild one = contactGroupBuildService.getOne(new QueryWrapper<ContactGroupBuild>()
                            .eq(ContactGroupBuild.BUILD_ID, communityBuilds.get(i).getId())
                            .eq(ContactGroupBuild.CONTACT_GROUP_ID, sysUser.getContactGroupId()));
                    if(one==null){
                        continue;
                    }
                    buildList.add(communityBuilds.get(i).getId());
                }
                for (int i = 0; i < buildList.size(); i++) {
                    buildId[i]=buildList.get(i);
                }
                communityResidentPage = this.communityResidentService.page(pager, queryWrapper.lambda().in(CommunityResident::getBuildId,buildId));
                records = communityResidentPage.getRecords();
                dataFormat(records);
            }else {
                communityResidentPage = this.communityResidentService.page(pager, queryWrapper.lambda());
                records = communityResidentPage.getRecords();
                dataFormat(records);
            }


        } else {
            if (type == 1) {
                communityResidentPage = this.communityResidentService.page(pager, queryWrapper.lambda()
                        .eq(CommunityResident::getTownShipId, id));
                records = communityResidentPage.getRecords();

                dataFormat(records);

            } else if (type == 2) {
                communityResidentPage = this.communityResidentService.page(pager, queryWrapper.lambda()
                        .eq(CommunityResident::getVillageId, id));
                records = communityResidentPage.getRecords();

                dataFormat(records);

            } else if (type == 3) {
                if(status==true){
                    String userId = SysUtils.currentUserId();
                    SysUser sysUser = sysUserService.getOne(new QueryWrapper<SysUser>().eq(SysUser.USER_ID, userId));
                    if (sysUser == null) {
                        return Result.error("该帐号不存在");
                    }
                    List<CommunityBuild> communityBuilds = communityBuildService.list(new QueryWrapper<CommunityBuild>().in(CommunityBuild.GRID_ID, id));
                    if (communityBuilds.size() == 0) {
                        return Result.ok().data(records);
                    }
                    List<Integer> buildList=new ArrayList<>();
                    Integer[] buildId= new Integer[communityBuilds.size()];
                    for (int i = 0; i < communityBuilds.size(); i++) {
                        ContactGroupBuild one = contactGroupBuildService.getOne(new QueryWrapper<ContactGroupBuild>()
                                .eq(ContactGroupBuild.BUILD_ID, communityBuilds.get(i).getId())
                                .eq(ContactGroupBuild.CONTACT_GROUP_ID, sysUser.getContactGroupId()));
                        if(one==null){
                            continue;
                        }
                        buildList.add(communityBuilds.get(i).getId());
                    }
                    for (int i = 0; i < buildList.size(); i++) {
                        buildId[i]=buildList.get(i);
                    }
                    communityResidentPage = this.communityResidentService.page(pager, queryWrapper.lambda().in(CommunityResident::getBuildId,buildId));
                    records = communityResidentPage.getRecords();

                    dataFormat(records);
                }else {
                    communityResidentPage = this.communityResidentService.page(pager, queryWrapper.lambda()
                            .eq(CommunityResident::getGridId, id));
                    records = communityResidentPage.getRecords();

                    dataFormat(records);
                }


            } else if (type == 4) {
                communityResidentPage = this.communityResidentService.page(pager, queryWrapper.lambda()
                        .eq(CommunityResident::getBuildId, id));
                records = communityResidentPage.getRecords();

                dataFormat(records);
            } else if (type == 5) {
                communityResidentPage = this.communityResidentService.page(pager, queryWrapper.lambda()
                        .eq(CommunityResident::getBuildDetailId, id));
                records = communityResidentPage.getRecords();

                dataFormat(records);
            }
        }

        Map<String, Object> map = new HashMap();
        map.put("pager", communityResidentPage);
        map.put("list", records);
        return Result.ok().data(map);

    }

    /**
     * 安置
     */
    @AutoLog
    @PutMapping("/placement")
    @Transactional(rollbackFor = {Exception.class})
    public Result placement(@RequestParam("id") String id, @RequestParam("fmailyId") Integer fmailyId) throws AlertException {
        String[] split = id.split(",");
        for (String s : split) {
            CommunityResident one = communityResidentService.getOne(new QueryWrapper<CommunityResident>().eq(CommunityResident.ID, Integer.parseInt(s)));
            if (one == null) {
                return Result.error("居民不存在");
            }
            if (one.getBuildDetailId() != 0) {
                return Result.error(one.getUserName() + " 居民已安置");
            }
            Boolean placement = communityResidentService.placement(one, fmailyId);
            if (!placement) {
                return Result.error("居民安置失败");
            }
        }
        return Result.ok("安置成功");

    }

    /**
     * 导入  按照楼导入居民
     */
    @AutoLog
    @PostMapping("/checkAndSave")
    public Result checkAndSave(@RequestParam("communityResident") MultipartFile communityResident) throws AlertException {
        /**
         * 保存正常的，返回异常的
         */
        Map<String, Object> map = communityResidentService.checkAndSave(communityResident);
        return Result.ok().data(map);
    }

    @AutoLog
    @GetMapping("/template")
    public void template(HttpServletResponse response) throws AlertException, IOException {
        File cfgFile = ResourceUtils.getFile("classpath:public/居民统一表头.xlsx");

        Faster.download(response, cfgFile);
    }

    public void dataFormat( List<CommunityResident> records){
        for (CommunityResident record : records) {
            if (record.getGender() == 0) {
                record.setGenderContent("女");
            } else {
                record.setGenderContent("男");
            }
            record.setIdCard(DesensitizationUtils.idEncrypt(record.getIdCard()));
        }

    }
}
